package org.mirrentools.attendance.console.service.impl;

import io.vertx.core.json.JsonArray;
import io.vertx.ext.sql.assist.SqlAndParams;
import org.mirrentools.attendance.console.common.FutureUtil;
import org.mirrentools.attendance.console.common.ResultCodeEnum;
import org.mirrentools.attendance.console.common.StringUtil;
import org.mirrentools.attendance.console.entity.Users;
import org.mirrentools.attendance.console.service.UsersService;
import org.mirrentools.attendance.console.sql.UsersSQL;
import org.mirrentools.attendance.console.sql.WriteListSQL;

import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import io.vertx.ext.jdbc.JDBCClient;
import io.vertx.ext.sql.assist.SQLExecute;
import io.vertx.ext.web.RoutingContext;

import java.util.ArrayList;
import java.util.List;

/**
 * Users数据服务接口的默认实现
 *
 * @author
 */
public class UsersServiceImpl implements UsersService {
  /**
   * 日志工具
   */
  private final Logger LOG = LoggerFactory.getLogger(this.getClass());
  /**
   * SQL操作语句
   */
  private UsersSQL usersSql;
  /**
   * 白名单操作语句
   */
  private WriteListSQL writeListSQL;

  /**
   * 初始化
   *
   * @param execute
   */
  public UsersServiceImpl(SQLExecute<JDBCClient> execute) {
    super();
    this.usersSql = new UsersSQL(execute);
    this.writeListSQL = new WriteListSQL(execute);
  }

  @Override
  public void checkToken(RoutingContext rct, Handler<AsyncResult<JsonObject>> handler) {
    //能进入这一步就代表已经通过了安全监测
    handler.handle(FutureUtil.successC200One());
  }

  @Override
  public void get(RoutingContext rct, Handler<AsyncResult<JsonObject>> handler) {
    String id = rct.request().getParam("uid");
    if (StringUtil.isNullOrEmpty(id)) {
      id = rct.request().remoteAddress().host();
    }
    usersSql.selectById(id, res -> {
      if (res.succeeded()) {
        JsonObject result = res.result();
        if (LOG.isDebugEnabled()) {
          LOG.debug("执行获取用户信息-->结果:" + result);
        }
        if (result == null || result.isEmpty()) {
          handler.handle(FutureUtil.successNewJson(ResultCodeEnum.C301));
          return;
        }
        handler.handle(FutureUtil.successC200(result));
      } else {
        LOG.error("执行获取用户信息-->失败:", res.cause());
        handler.handle(FutureUtil.successC500NewJson());
      }
    });
  }

  @Override
  public void findUsers(RoutingContext rct, Handler<AsyncResult<JsonObject>> handler) {
    String id = rct.request().getParam("uid");
    if (StringUtil.isNullOrEmpty(id)) {
      id = rct.request().remoteAddress().host();
    }
    String sql = "SELECT id,nickname FROM users WHERE 1=(SELECT 1 FROM users WHERE id=? AND state=1)";
    JsonArray sqldata = new JsonArray().add(id);
    usersSql.queryAsListObj(new SqlAndParams(sql, sqldata), res -> {
      if (res.succeeded()) {
        List<JsonObject> result = res.result() == null ? new ArrayList<>() : res.result();
        if (LOG.isDebugEnabled()) {
          LOG.debug("执行获取用户列表-->结果:" + result);
        }
        handler.handle(FutureUtil.successC200(result));
      } else {
        LOG.error("执行获取用户列表-->失败:", res.cause());
        handler.handle(FutureUtil.successC500NewJson());
      }
    });
  }

  @Override
  public void post(RoutingContext rct, Handler<AsyncResult<JsonObject>> handler) {
    String id = rct.request().getParam("id");
    if (StringUtil.isNullOrEmpty(id)) {
      id = rct.request().remoteAddress().host();
    }
    String nickname = rct.request().getParam("nickname");
    if (StringUtil.isNullOrEmpty(nickname)) {
      handler.handle(FutureUtil.successC412Zero());
      return;
    }
    Users users = new Users();
    users.setId(id).setNickname(nickname);
    writeListSQL.selectById(id, filter -> {
      if (filter.succeeded()) {
        if (LOG.isDebugEnabled()) {
          LOG.debug("执行新建用户->查询白名单-->结果:" + filter.result());
        }
        if (StringUtil.isNullOrEmpty(filter.result())) {
          handler.handle(FutureUtil.successC500Zero("认证不通过,你不在白名单中,请联系管理员!"));
          return;
        }
        usersSql.replace(users, res -> {
          if (res.succeeded()) {
            Integer result = res.result();
            if (LOG.isDebugEnabled()) {
              LOG.debug("执行新建用户-->结果:" + result);
            }
            handler.handle(FutureUtil.successC200(result));
          } else {
            String message = res.cause().getMessage();
            LOG.error("执行新建用户-->失败:", res.cause());
            handler.handle(FutureUtil.successC500Zero("认证失败,请联系管理员!", message));
          }
        });
      } else {
        String message = filter.cause().getMessage();
        LOG.error("执行新建用户->查询白名单-->失败:", filter.cause());
        handler.handle(FutureUtil.successC500Zero("认证失败,白名单认证不通过,请联系管理员!", message));
      }
    });
  }
}
